home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 011 / setalarm.arc / SETALARM.ASM next >
Encoding:
Assembly Source File  |  1986-04-02  |  6.4 KB  |  182 lines

  1. ;----------------------------------------------------------
  2. ; Set the PC/AT alarm to user-specified time.  Points alarm
  3. ; vector to BEEPER procedure which remains resident.
  4. ;-----------------------------------------------------------
  5. ; (c) Copyright Leo J. Scanlon, 1986
  6. .286c
  7.  
  8. PRINT$  MACRO  STRING          ; Macro that prints a string
  9.         LEA   DX,STRING
  10.         MOV   AH,9
  11.         INT   21H              ;Function 9: display string
  12.         ENDM
  13.  
  14. PROGRAM SEGMENT PARA PUBLIC 'CODE'
  15.         ASSUME CS:PROGRAM,DS:PROGRAM,ES:PROGRAM,SS:PROGRAM
  16.         ORG 100H              ;designed as .COM file
  17.  
  18. BEGINNING:
  19.         JMP MAIN              ;jump around procs and data
  20.  
  21. START_RESIDENT:
  22.  
  23. BEEPER   PROC
  24.         PUSHA               ;Save the user's registers
  25.         MOV   CX,5          ;Beep five times
  26. BEEP:   MOV   AL,7          ;Beep for one second
  27.         MOV   AH,0EH
  28.         INT   10H           ;Video EH: write char as TTY
  29.         LOOP  BEEP
  30.         POPA                ;Restore the registers
  31.         IRET
  32. BEEPER   ENDP
  33.  
  34. END_RESIDENT:
  35. RESIDENT_LENGTH EQU END_RESIDENT - START_RESIDENT
  36. RESIDENT_OFFSET EQU START_RESIDENT - BEGINNING + 100H
  37.  
  38. ;----------------------------------------------------------------
  39. ; See if BEEPER proc is already resident.  Sets FIRST_TIME?=0 if
  40. ; alarm vector 4AH points to beeper routine, else leaves it 1
  41. ;----------------------------------------------------------------
  42. FIRST_TIME?     DB 1
  43. CHECK_BEEPER    PROC
  44.                 MOV AH, 35H
  45.                 MOV AL, 4AH
  46.                 INT 21H       ;function 35H (get interrupt vector)
  47.                 MOV DI,BX                    ; set up ES:DI
  48.                 MOV SI,[RESIDENT_OFFSET]     ; address BEEPER
  49.                                              ; with DS:SI
  50.                 MOV CX,[RESIDENT_LENGTH]     ; set length for CMPS
  51.                 REPE CMPSB
  52.                 JZ ALREADY_THERE             ; ZF set means match
  53.                 RET
  54. ALREADY_THERE:  MOV FIRST_TIME?,0
  55.                 RET
  56. CHECK_BEEPER    ENDP
  57.  
  58. ;------------------------------------------------------
  59. ; data area: messages, prompts, and keystroke buffer.
  60. ;------------------------------------------------------
  61.  
  62. CRLF     DB   13,10,'$'
  63. BAD_DATA DB   'Digits must be between 0 and 9',13,10,'$'
  64. BAD_HRS  DB   'Hours must be between 0 and 23',13,10,'$'
  65. BAD_MINS DB   'Minutes must be between 0 and 59',13,10,'$'
  66. BAD_SECS DB   'Seconds must be between 0 and 59',13,10,'$'
  67.  
  68. PROMPT  DB    'Set the alarm time.',13,10
  69.         DB    'Enter values or press Enter for zero'
  70.         DB    13,10,'$'
  71. ASK_HRS DB    'Hour (0-23): $'
  72. ASK_MINS DB   'Minute (0-59): $'
  73. ASK_SECS DB   'Second (0-59): $'
  74. USER$   DB    3,4 DUP(?)
  75.               ; User's response in 5 byte buffer
  76.               ; <length of buffer> <chars read> <char1> <char2> <ret>
  77.  
  78. ;---------------------------------------------------------------
  79. ; GET_TIME reads up to two keys into string buffer USER$,
  80. ; then converts them into a packed BCD number in BL.
  81. ; If either key is invalid, it prints an error message and sets
  82. ; CF to 1.
  83. ;---------------------------------------------------------------
  84.  
  85. GET_TIME PROC
  86.         LEA   DX,USER$     ;Read user's response
  87.         MOV   AH,0AH
  88.         INT   21H          ; function AH (get keyboard input)
  89. stop1:  PRINT$  CRLF       ;Advance to next line
  90.         CMP   USER$+1,1    ;Check key count
  91.         JAE   CONVERT
  92.         SUB   BL,BL         ;User pressed Enter
  93.         RET
  94. CONVERT: MOV  AL,USER$+2   ;Get first key
  95.         CALL  CHECK         ;Check this character
  96.         JC    LEAVE         ;If it is valid,
  97.         AND   AL,0FH        ; convert it to BCD
  98.         MOV   BL,AL
  99.         CMP   USER$+1,2    ;Is there another key?
  100.         JB    CLR_CF
  101.         SHL   BL,4          ;Yes. Put first digit in high bits
  102.         MOV   AL,USER$+3    ;Get second key
  103.         CALL  CHECK         ;Check this character
  104.         JC    LEAVE         ;If it is valid,
  105.         AND   AL,0FH        ; convert it to BCD
  106.         OR    BL,AL
  107. CLR_CF: CLC
  108. LEAVE:  RET
  109. GET_TIME ENDP
  110.  
  111. ;-----------------------------------------------------------
  112. ; CHECK makes sure an entry value is between 0 and
  113. ; 9.  If not, it displays an error message and sets CF to 1.
  114. ;-----------------------------------------------------------
  115.  
  116.  
  117. CHECK   PROC
  118.         CMP   AL,'0'        ;If entry is < 0
  119.         JB    ERROR
  120.         CMP   AL,'9'        ; or > 9,
  121.         JA    ERROR         ; print message
  122.         CLC                 ;Otherwise, clear CF and return
  123.         RET
  124. ERROR:  PRINT$  BAD_DATA    ;Display error message
  125.         STC                 ;Set CF and return
  126.         RET
  127. CHECK   ENDP
  128.  
  129. MAIN    PROC NEAR
  130.         MOV   AH,7          ;Reset the alarm
  131.         INT   1AH           ; AT BIOS interrupt 1AH (reset alarm)
  132.         CALL  CHECK_BEEPER
  133.         CMP   FIRST_TIME?, 1
  134.         JNE   USER_INPUT
  135.         MOV   AL,4AH        ;Make the 4A vector point to BEEPER
  136.         LEA   DX,BEEPER
  137.         MOV   AH,25H
  138.         INT   21H           ;function 25H (set interrupt vector)
  139.  
  140. USER_INPUT:
  141.         PRINT$  PROMPT     ;Ask for alarm hour
  142. HOUR:   PRINT$  ASK_HRS
  143.         CALL  GET_TIME     ;Convert it to BCD
  144.         JC    HOUR
  145.         CMP   BL,23H        ;Make sure it's < 24
  146.         JNA   HRS2CH
  147.         PRINT$  BAD_HRS
  148.         JMP   HOUR
  149. HRS2CH: MOV   CH,BL         ; and put it in CH
  150.  
  151. MIN:    PRINT$  ASK_MINS   ;Ask for alarm minutes
  152.         CALL  GET_TIME     ;Convert it to BCD
  153.         JC    MIN
  154.         CMP   BL,59H        ;Make sure it's < 60
  155.         JNA   MIN2CL
  156.         PRINT$  BAD_MINS
  157.         JMP   MIN
  158. MIN2CL: MOV   CL,BL         ; and put it in CL
  159.  
  160. SEC:    PRINT$  ASK_SECS   ;Ask for alarm seconds
  161.         CALL  GET_TIME     ;Convert it to BCD
  162.         JC    SEC
  163.         CMP   BL,59H        ;Make sure it's < 60
  164.         JNA   SEC2DH
  165.         PRINT$  BAD_SECS
  166.         JMP   SEC
  167. SEC2DH: MOV   DH,BL         ; and put it in DH
  168.         MOV   AH,6
  169.         INT   1AH           ;AT BIOS interrupt 1AH (set alarm)
  170.         CMP   FIRST_TIME?, 1
  171.         JNE   CLEAR_OUT
  172.         MOV   DX, RESIDENT_OFFSET + RESIDENT_LENGTH
  173.                             ;first invocation - leave BEEPER resident
  174.         INT   27H           ;interrupt 27H (terminate, stay resident)
  175.  
  176. CLEAR_OUT:
  177.         RET                 ;BEEPER already in place so
  178.                             ;exit normally
  179. MAIN    ENDP
  180. PROGRAM ENDS
  181.         END BEGINNING
  182.